# -*- coding: utf-8 -*-
"""
菜单管理模块
提供菜单栏的创建和相关功能
"""

# 在任何tkinter导入之前设置环境
import sys
import os
from modules.tkinter_setup import setup_tcltk_environment
setup_tcltk_environment()

import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
from modules.ui.settings_manager import SettingsManager


class MenuManager:
    """菜单管理器"""
    
    def __init__(self, root, config_manager, save_config_callback, hotkey_update_callback=None, tray_manager=None):
        """初始化菜单管理器
        
        Args:
            root: Tkinter根窗口
            config_manager: 配置管理器实例
            save_config_callback: 保存配置的回调函数
            hotkey_update_callback: 热键更新回调函数
            tray_manager: 托盘管理器实例
        """
        self.root = root
        self.config = config_manager
        self.save_config_callback = save_config_callback
        self.hotkey_update_callback = hotkey_update_callback
        self.tray_manager = tray_manager
        
        # 初始化设置管理器
        self.settings_manager = SettingsManager(
            root, 
            config_manager, 
            hotkey_update_callback
        )  # 设置窗口实例（防止重复打开）
        
        # 设置日志文件路径（兼容打包后的exe路径）
        if getattr(sys, 'frozen', False):
            self._base_dir = os.path.dirname(sys.executable)
        else:
            self._base_dir = os.path.dirname(os.path.abspath(__file__))
    
    def _center_window(self, window):
        """
        将窗口居中显示在桌面
        
        Args:
            window: Toplevel窗口对象
        """
        window.update_idletasks()  # 确保窗口大小已更新
        width = window.winfo_width()
        height = window.winfo_height()
        
        # 获取屏幕尺寸
        screen_width = window.winfo_screenwidth()
        screen_height = window.winfo_screenheight()
        
        # 计算居中位置
        x = (screen_width - width) // 2
        y = (screen_height - height) // 2
        
        # 设置窗口位置
        window.geometry(f"{width}x{height}+{x}+{y}")
    
    def create_menu_bar(self):
        """创建菜单栏"""
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)
        
        # 编辑菜单
        edit_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="编辑", menu=edit_menu)
        edit_menu.add_command(label="保存", command=self.menu_save_config, accelerator="Ctrl+S")
        
        # 绑定快捷键
        self.root.bind('<Control-s>', lambda e: self.menu_save_config())
        
        # 工具菜单
        tools_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="工具", menu=tools_menu)
        tools_menu.add_command(label="属性", command=self.show_settings)
        tools_menu.add_separator()
        tools_menu.add_command(label="托盘状态排查", command=self.show_tray_status)
        
        # 帮助菜单
        help_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="帮助", menu=help_menu)
        help_menu.add_command(label="使用说明", command=self.show_usage_help)
        help_menu.add_command(label="关于", command=self.show_about)
    
    def menu_save_config(self):
        """菜单：保存配置"""
        if self.save_config_callback:
            self.save_config_callback()
            messagebox.showinfo("提示", "配置已保存")
    
    def show_usage_help(self):
        """显示使用说明"""
        help_window = tk.Toplevel(self.root)
        help_window.title("使用说明")
        help_window.geometry("600x500")
        
        # 设置为模态窗口
        help_window.transient(self.root)
        help_window.grab_set()
        
        # 居中窗口
        self._center_window(help_window)
        
        # 创建文本显示区域
        text_frame = ttk.Frame(help_window)
        text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        help_text = scrolledtext.ScrolledText(text_frame, wrap=tk.WORD, font=('Arial', 10))
        help_text.pack(fill=tk.BOTH, expand=True)
        
        # 读取使用说明内容
        help_content = self._get_usage_help_content()
        help_text.insert('1.0', help_content)
        help_text.config(state=tk.DISABLED)
        
        # 关闭按钮
        btn_frame = ttk.Frame(help_window)
        btn_frame.pack(pady=10)
        ttk.Button(btn_frame, text="关闭", command=help_window.destroy).pack()
    
    def show_about(self):
        """显示关于对话框"""
        about_window = tk.Toplevel(self.root)
        about_window.title("关于")
        about_window.geometry("500x400")
        
        # 设置为模态窗口
        about_window.transient(self.root)
        about_window.grab_set()
        
        # 居中窗口
        self._center_window(about_window)
        
        # 创建文本显示区域
        text_frame = ttk.Frame(about_window)
        text_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
        
        # 标题
        title_label = ttk.Label(text_frame, text="Windows Process Spy", 
                               font=('Arial', 16, 'bold'))
        title_label.pack(pady=(0, 10))
        
        # 使用说明内容
        help_text = scrolledtext.ScrolledText(text_frame, wrap=tk.WORD, 
                                             font=('Arial', 10), height=15)
        help_text.pack(fill=tk.BOTH, expand=True)
        
        # 读取使用说明内容
        help_content = self._get_usage_help_content()
        help_text.insert('1.0', help_content)
        help_text.config(state=tk.DISABLED)
        
        # 关闭按钮
        btn_frame = ttk.Frame(about_window)
        btn_frame.pack(pady=10)
        ttk.Button(btn_frame, text="关闭", command=about_window.destroy).pack()
    
    def _get_usage_help_content(self):
        """获取使用说明内容"""
        try:
            # 尝试读取使用说明文件
            help_file = os.path.join(self._base_dir, "release", "使用说明.txt")
            if os.path.exists(help_file):
                with open(help_file, 'r', encoding='utf-8') as f:
                    return f.read()
            
            # 如果文件不存在，返回默认内容
            return """Windows Process Spy - 使用说明

文件说明:
- WindowSpyGUI.exe: 图形界面版本，双击运行
- WindowSpyCLI.exe: 命令行版本，在命令行中运行

图形界面版本使用方法:
1. 双击 WindowSpyGUI.exe 运行
2. 点击"刷新窗口列表"查看所有窗口
3. 选择窗口查看其控件信息
4. 使用搜索框快速查找窗口

命令行版本使用方法:
WindowSpyCLI.exe --help                    # 查看帮助
WindowSpyCLI.exe --list                    # 列出所有窗口
WindowSpyCLI.exe --title "记事本"          # 查找记事本窗口
WindowSpyCLI.exe --process "notepad"       # 查找记事本进程的窗口
WindowSpyCLI.exe --hwnd 123456             # 查看指定句柄的窗口

注意事项:
- 需要Windows 10/11系统
- 某些系统窗口可能需要管理员权限才能访问
- 程序运行时请勿关闭杀毒软件

版本信息:
- 版本: 1.0.0
- 开发语言: Python 3
- 打包工具: PyInstaller"""
        except Exception as e:
            return f"读取使用说明失败: {e}"
    
    def show_settings(self):
        """显示属性设置窗口（使用独立的设置管理器）"""
        self.settings_manager.show_settings()
    
    def _on_setting_selected(self):
        """设置项选择变化时的处理"""
        selection = self._settings_listbox.curselection()
        if not selection:
            return
        
        selected_index = selection[0]
        
        # 隐藏当前设置内容
        if hasattr(self, '_current_settings_frame'):
            self._current_settings_frame.pack_forget()
        
        # 显示对应的设置内容
        if selected_index == 0:  # 截图
            self._current_settings_frame = self._screenshot_settings_frame
        else:
            # 其他设置项（预留）
            if self._other_settings_frame is None:
                self._other_settings_frame = ttk.Frame(self._right_frame)
                ttk.Label(self._other_settings_frame, text="其他设置项（预留）").pack()
            self._current_settings_frame = self._other_settings_frame
        
        self._current_settings_frame.pack(fill=tk.BOTH, expand=True)
    
    def _on_hide_main_window_changed(self):
        """截图时隐藏主窗口选项变化时的处理"""
        value = self._hide_main_window_var.get()
        self.config.set_screenshot_hide_main_window(value)
        self.config.save()
    
    def _apply_hotkey_start(self):
        """应用开始截图快捷键"""
        try:
            hotkey = self._hotkey_start_var.get().strip()
            if not hotkey:
                hotkey = 'ctrl+alt+i'
            
            # 保存到配置
            self.config.set_hotkey_start(hotkey)
            self.config.save()
            
            # 通知主窗口重新应用快捷键
            if self.hotkey_update_callback:
                try:
                    self.hotkey_update_callback()
                    from tkinter import messagebox
                    messagebox.showinfo("提示", f"开始截图快捷键已设置为: {hotkey}")
                except Exception as e:
                    from tkinter import messagebox
                    messagebox.showinfo("提示", f"快捷键已保存，将在下次启动时生效: {e}")
            else:
                from tkinter import messagebox
                messagebox.showinfo("提示", f"开始截图快捷键已设置为: {hotkey}\n程序将自动重新应用快捷键")
        except Exception as e:
            from tkinter import messagebox
            messagebox.showerror("错误", f"设置快捷键失败: {e}")
    
    def _apply_hotkey_full(self):
        """应用全屏截图快捷键"""
        try:
            hotkey = self._hotkey_full_var.get().strip()
            if not hotkey:
                hotkey = 'ctrl+alt+shift+i'
            
            # 保存到配置
            self.config.set_hotkey_full(hotkey)
            self.config.save()
            
            # 通知主窗口重新应用快捷键
            if self.hotkey_update_callback:
                try:
                    self.hotkey_update_callback()
                    from tkinter import messagebox
                    messagebox.showinfo("提示", f"全屏截图快捷键已设置为: {hotkey}")
                except Exception as e:
                    from tkinter import messagebox
                    messagebox.showinfo("提示", f"快捷键已保存，将在下次启动时生效: {e}")
            else:
                from tkinter import messagebox
                messagebox.showinfo("提示", f"全屏截图快捷键已设置为: {hotkey}\n程序将自动重新应用快捷键")
        except Exception as e:
            from tkinter import messagebox
            messagebox.showerror("错误", f"设置快捷键失败: {e}")
    
    def show_tray_status(self):
        """显示托盘状态排查窗口"""
        status_window = tk.Toplevel(self.root)
        status_window.title("托盘状态排查")
        status_window.geometry("600x500")
        
        # 设置为模态窗口
        status_window.transient(self.root)
        status_window.grab_set()
        
        # 居中窗口
        self._center_window(status_window)
        
        # 创建文本显示区域
        text_area = scrolledtext.ScrolledText(status_window, wrap=tk.WORD, font=('Consolas', 9))
        text_area.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 收集状态信息
        status_info = []
        status_info.append("=" * 60)
        status_info.append("托盘状态排查信息")
        status_info.append("=" * 60)
        status_info.append("")
        
        # 窗口状态
        try:
            window_state = self.root.state()
            window_visible = self.root.winfo_viewable()
            window_geometry = self.root.geometry()
            status_info.append(f"[窗口状态]")
            status_info.append(f"  Tkinter状态: {window_state}")
            status_info.append(f"  可见性: {window_visible}")
            status_info.append(f"  几何尺寸: {window_geometry}")
            status_info.append("")
        except Exception as e:
            status_info.append(f"[窗口状态] 获取失败: {e}")
            status_info.append("")
        
        # 托盘管理器状态
        if self.tray_manager:
            try:
                is_hidden = self.tray_manager.is_hidden()
                status_info.append(f"[托盘管理器]")
                status_info.append(f"  管理器存在: 是")
                status_info.append(f"  是否隐藏到托盘: {is_hidden}")
                status_info.append(f"  _is_hidden_to_tray: {self.tray_manager._is_hidden_to_tray if hasattr(self.tray_manager, '_is_hidden_to_tray') else 'N/A'}")
                status_info.append("")
            except Exception as e:
                status_info.append(f"[托盘管理器] 获取失败: {e}")
                status_info.append("")
        else:
            status_info.append(f"[托盘管理器]")
            status_info.append(f"  管理器存在: 否")
            status_info.append("")
        
        # Windows API 窗口状态
        try:
            import win32gui
            import win32con
            
            hwnd = self.root.winfo_id()
            if hwnd:
                # 获取窗口句柄（Tkinter窗口ID）
                try:
                    # 尝试通过窗口标题查找
                    def enum_handler(hwnd_param, ctx):
                        if win32gui.IsWindowVisible(hwnd_param):
                            title = win32gui.GetWindowText(hwnd_param)
                            if "Windows Process Spy" in title or "窗口句柄检测工具" in title:
                                ctx.append((hwnd_param, title))
                    
                    windows = []
                    win32gui.EnumWindows(enum_handler, windows)
                    
                    status_info.append(f"[Windows API]")
                    if windows:
                        for hwnd_win, title in windows[:3]:  # 最多显示3个
                            is_minimized = win32gui.IsIconic(hwnd_win)
                            is_maximized = win32gui.IsZoomed(hwnd_win)
                            is_visible = win32gui.IsWindowVisible(hwnd_win)
                            status_info.append(f"  窗口: {title}")
                            status_info.append(f"    句柄: {hwnd_win}")
                            status_info.append(f"    最小化: {is_minimized}")
                            status_info.append(f"    最大化: {is_maximized}")
                            status_info.append(f"    可见: {is_visible}")
                    else:
                        status_info.append(f"  未找到匹配的窗口")
                    status_info.append("")
                except Exception as e:
                    status_info.append(f"[Windows API] 枚举失败: {e}")
                    status_info.append("")
        except ImportError:
            status_info.append(f"[Windows API] win32gui未安装")
            status_info.append("")
        except Exception as e:
            status_info.append(f"[Windows API] 获取失败: {e}")
            status_info.append("")
        
        # 系统托盘图标
        try:
            status_info.append(f"[系统托盘]")
            status_info.append(f"  注意: Windows系统托盘图标需要专门的API创建")
            status_info.append(f"  当前实现: 仅使用窗口隐藏/显示")
            status_info.append("")
        except Exception as e:
            status_info.append(f"[系统托盘] 获取失败: {e}")
            status_info.append("")
        
        # 日志文件位置
        try:
            log_file = os.path.join(self._base_dir, "screenshot_debug.log")
            if os.path.exists(log_file):
                file_size = os.path.getsize(log_file)
                status_info.append(f"[日志文件]")
                status_info.append(f"  路径: {log_file}")
                status_info.append(f"  大小: {file_size} 字节")
                status_info.append(f"  存在: 是")
            else:
                status_info.append(f"[日志文件]")
                status_info.append(f"  路径: {log_file}")
                status_info.append(f"  存在: 否")
            status_info.append("")
        except Exception as e:
            status_info.append(f"[日志文件] 获取失败: {e}")
            status_info.append("")
        
        status_info.append("=" * 60)
        status_info.append("提示: 如果窗口已隐藏到托盘，可以通过以下方式显示：")
        status_info.append("  1. 如果任务栏有图标，右键点击")
        status_info.append("  2. 如果托盘图标存在，右键点击托盘图标")
        status_info.append("  3. 重新运行程序（单例模式会阻止）")
        status_info.append("=" * 60)
        
        # 显示信息
        text_area.insert(tk.END, "\n".join(status_info))
        text_area.config(state=tk.DISABLED)
        
        # 添加刷新按钮
        btn_frame = ttk.Frame(status_window)
        btn_frame.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        def refresh_status():
            text_area.config(state=tk.NORMAL)
            text_area.delete(1.0, tk.END)
            # 重新收集状态（简化版，只刷新关键信息）
            refresh_info = []
            refresh_info.append("状态已刷新（重新打开窗口可查看完整信息）")
            refresh_info.append("")
            try:
                window_state = self.root.state()
                refresh_info.append(f"窗口状态: {window_state}")
            except:
                pass
            try:
                if self.tray_manager:
                    refresh_info.append(f"是否隐藏到托盘: {self.tray_manager.is_hidden()}")
            except:
                pass
            text_area.insert(tk.END, "\n".join(refresh_info))
            text_area.config(state=tk.DISABLED)
        
        ttk.Button(btn_frame, text="刷新", command=refresh_status).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="关闭", command=status_window.destroy).pack(side=tk.RIGHT, padx=5)

